//{=================================================================================
//! @file    dz1.cpp
//! @date    2014-09-18 11:38
//! @author  Dima Samchenko <samchenko.da@gmail.com>, 471 group
//!
//! 10 home tasks from lesson 22.09.2014
//!
//! @par     Solves of tasks.
//!          Conditions of problems: http://acm.mipt.ru/twiki/pub/Cintro/CTestMIPT2007/test_main.pdf
//!
//}=================================================================================
//--------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include <ctype.h>


//--------------------------------------------------------------------------
// #define MY_COMPUTER
//--------------------------------------------------------------------------
#ifdef MY_COMPUTER
    #define OUT printf("#"), //! debug output
#else
    #define OUT if(0) //! normal output
#endif

//--------------------------------------------------------------------------
// #define ASSERT
//--------------------------------------------------------------------------
#ifndef NDEBUG
    #define ASSERT(cond)  if(!(cond))\
                          {\
                              printf("FAIL: %s, in %s, %d, %s\n",\
                              #cond, __FILE__, __LINE__, __PRETTY_FUNCTION__);\
                              abort();\
                          }
#else
    #define ;
#endif

#define sqr(x) ((x) * (x))
#define max(x, y) ((x) > (y))? (x): (y)

//! The values returned if result is false or true
enum checking{FALSE, TRUE};

//! ERROR - The value returned if result is incorrect
//! OK    - The value returned if result is correct and procedure is done
enum result{ERROR = -1, OK = 1};

//! The value of max prime number plus 1(for using this const in arrays)
int const MaxValueOfPrimeNumber = 104730;

//! Number of primes plus 1(for using this const in arrays)
int const NumberOfPrimes = 10001;



/** ********************************************************************************
 Task_1C_Weighing - Variant 1 task C.

 @return   OK or ERROR

************************************************************************************/
int Task_1C_Weighing();

/** ********************************************************************************
 Weighing - recurrently procedure which checks can be the number n weighed.

 @param      Number   Current "weigh"

 @return              True or false according with param Number modulo 4

************************************************************************************/
int Weighing(int n);

/** ********************************************************************************
 Task_2C_PrimeNumber - Variant 2 task C.

 @return    OK or ERROR

************************************************************************************/
int Task_2C_PrimeNumber();

/** ********************************************************************************
 CreateMassOfPrimes -       creating array of prime numbers.

 @param[out] massOfPrimes   array of prime numbers

************************************************************************************/
void CreateMassOfPrimes(int massOfPrimes[]);

/** ********************************************************************************
 CreateMass_checkPrime -    creating array that taking the value 0 or 1:
                            massOfPrimes[number] = 0 means that number is prime.
                            massOfPrimes[number] = 1 means that number is not prime.

 @param[out] massOfPrimes   array that taking the value 0 or 1

************************************************************************************/
void CreateMass_checkPrime(int checkPrime[]);

/** ********************************************************************************
 SelectTask - selecting number of task.

 @param[out] numberOfTask   number of selected task

 @return OK or ERROR

************************************************************************************/
int SelectTask(int* numberOfTask);

/** ********************************************************************************
 DoTask - realization the task.

 @param[out] numberOfTask   number of selected task

 @return OK or ERROR

************************************************************************************/
int DoTask(int* numberOfTask);

/** ********************************************************************************
 Task_4C_FlipWord - Variant 4 task C.

 @return    OK or ERROR

************************************************************************************/
int Task_4C_FlipWord();

/** ********************************************************************************
 Task_3C_SumOfFourSquares - Variant 3 task C.

 @return   OK or ERROR

************************************************************************************/
int Task_3C_SumOfFourSquares();

/** ********************************************************************************
 Brute - searching for parametrs a, b, c, d: N = a^2 + b^2 + c^2 + d^2.

 @param      N   input number from Variant 3 task C
 @param[out] a   required number from condition Variant 3 task C
 @param[out] b   required number from condition Variant 3 task C
 @param[out] c   required number from condition Variant 3 task C
 @param[out] d   required number from condition Variant 3 task C

 @return    OK or ERROR

************************************************************************************/
int Brute(int N, int* a, int* b, int* c, int* d);

/** ********************************************************************************
 Task_6C_FreeFromSquares - Variant 6 task C.

 @return   OK or ERROR

************************************************************************************/
int Task_6C_FreeFromSquares();

/** ********************************************************************************
 ElemHasntSqruares - checks if element has no full square dividers

 @param massOfPrimes    array of prime numbers
 @param elem            element which is checking

 @return   True if has not or False if has

************************************************************************************/
bool ElemHasntSqruares(int massOfPrimes[], int elem);

/** ********************************************************************************
 Task_9C_SumOfBigBinaryNumbers - Variant 9 task C.

 @return   OK or ERROR

************************************************************************************/
int Task_9C_SumOfBigBinaryNumbers();

/** ********************************************************************************
 swap - swap x and y.

 @param[out] x
 @param[out] y

************************************************************************************/
void swap(int* x, int* y);

/** ********************************************************************************
 Task_5D_NumberOfGoodWords - Variant 5 task D.

 @return   OK or ERROR

************************************************************************************/
int Task_5D_NumberOfGoodWords();

/** ********************************************************************************
 RecursiveBrute - recurrent brute of all binary numbers satisfying condition of task.

 @param      N          input length of binary numbers from Variant 5 task D
 @param      K          input length of ones in binary numbers from Variant 5 task D
 @param      lastByte   last byte(0 or 1) of binary number
 @param[out] result     number of binary numbers satisfying condition of task

************************************************************************************/
void RecursiveBrute(int N, int K, int lastByte, long long* result);

/** ********************************************************************************
 Task_5C_SortingStudents - Variant 5 task C.

 @return   OK or ERROR

************************************************************************************/
int Task_5C_SortingStudents();

/** ********************************************************************************
 Task_5B_SumOfDividers - Variant 5 task B.

 @return   OK or ERROR

************************************************************************************/
int Task_5B_SumOfDividers();

/** ********************************************************************************
 Task_8B_FullSquares - Variant 5 task B.

 @return   OK or ERROR

************************************************************************************/
int Task_8B_FullSquares();

/** ********************************************************************************
 IsSquare - checks if element is square.

 @param      elem    checking element

 @return     enum TRUE or enum FALSE

************************************************************************************/
int IsSquare(int elem);


int main()
{
    int numberOfTask = 0;

    int checkSelectTask = SelectTask(&numberOfTask);
    ASSERT(checkSelectTask == OK);

    return 0;
}

int SelectTask(int* numberOfTask)
{
    ASSERT(numberOfTask != 0);
    OUT printf("Select task: write number of task(1-9) or 0 if you want to exit:\n\
                1  - Task Weighing(Variant 1 #C)\n\
                2  - Task Prime Number(Variant 2 #C)\n\
                3  - Task Sum of four squares(variant 3 #C)\n\
                4  - Task Flipping Word(Variant 4 #C)\n\
                5  - Task Numbers, free from squares(Variant 6 #C)\n\
                6  - Task Sum of big binary numbers(Variant 9 #C)\n\
                7  - Task Number Of Good Words(Variant 5 #D)\n\
                8  - Task Sum of Dividers(Variant 5 #B)\n\
                9  - Task Full Squares(Variant 8 #B)\n\
                10 - Task Sorting Students(Variant 5 #C)\n\
                0 - If you want to exit\n");
    if (scanf("%d", numberOfTask) != 1)
    {
        OUT printf("ERROR. Bad input. For example: 1\n");
        return ERROR;
    }
    char c = ' ';
    scanf("%c", &c);
    ASSERT(0 <= *numberOfTask && *numberOfTask <= 10);

    int checkDoTask = DoTask(numberOfTask);
    ASSERT(checkDoTask == OK);

    return OK;

}

int DoTask(int* numberOfTask)
{
    ASSERT(numberOfTask != 0);
    int checkingTask = 0;

    switch (*numberOfTask)
    {
        case 1:
            checkingTask = Task_1C_Weighing();
            ASSERT(checkingTask = OK);
            break;
        case 2:
            checkingTask = Task_2C_PrimeNumber();
            ASSERT(checkingTask = OK);
            break;
        case 3:
            checkingTask = Task_3C_SumOfFourSquares();
            ASSERT(checkingTask = OK);
            break;
        case 4:
            checkingTask = Task_4C_FlipWord();
            ASSERT(checkingTask = OK);
            break;
        case 5:
            checkingTask = Task_6C_FreeFromSquares();
            ASSERT(checkingTask = OK);
            break;
        case 6:
            checkingTask = Task_9C_SumOfBigBinaryNumbers();
            ASSERT(checkingTask = OK);
            break;
        case 7:
            checkingTask = Task_5D_NumberOfGoodWords();
            ASSERT(checkingTask = OK);
            break;
        case 8:
            checkingTask = Task_5B_SumOfDividers();
            ASSERT(checkingTask = OK);
            break;
        case 9:
            checkingTask = Task_8B_FullSquares();
            ASSERT(checkingTask = OK);
            break;
        case 10:
            checkingTask = Task_5C_SortingStudents();
            ASSERT(checkingTask = OK);
            break;
        case 0:
            OUT printf("Goodbye! :)\n");
            return OK;
            break;
        default:
            OUT printf("Sorry, something went wrong...\n");
            return ERROR;
            break;
    }

    int checkSelectTask = SelectTask(numberOfTask);
    ASSERT(checkSelectTask == OK);

    return OK;
}

int Task_1C_Weighing()
{
    int Number = 0;
    int minNumberValue = 0,
        maxNumberValue = INT_MAX;
    OUT printf("Enter your number>\n");
    if (scanf("%d", &Number) != 1)
    {
        OUT printf("ERROR. Bad input. For example: 58\n");
        return ERROR;
    }
    ASSERT(minNumberValue <= Number && Number < maxNumberValue); //! checking correct input

    int checkWeighing = Weighing(Number);
    ASSERT(checkWeighing == TRUE || checkWeighing == FALSE);
    switch (checkWeighing)
    {
        case TRUE:
            OUT printf("OK! This number can be weighed.\n");
            printf("YES\n");
            break;
        case FALSE:
            OUT printf("It's bad, but this number can't be weighed. :(\n");
            printf("NO\n");
            break;
        default:
            OUT printf("Sorry, something went wrong\n");
            return ERROR;
            break;
    }
    return OK;
}

int Weighing(int Number)
{
    if (Number == 0) return TRUE;
    int nModulo4 = Number % 4;
    ASSERT(0 <= nModulo4 && nModulo4 <= 3);
    switch (nModulo4)
    {
        case 0:
            return Weighing( Number      / 4);
            break;
        case 1:
            return Weighing((Number - 1) / 4);
            break;
        case 2:
            return FALSE;
            break;
        case 3:
            return Weighing((Number + 1) / 4);
            break;
        default:
            return ERROR;
    }
}

int Task_2C_PrimeNumber()
{
    int primeNumber = 0;

    OUT printf("Enter number of prime:\n");

    if (scanf("%d", &primeNumber) != 1)
    {
        OUT printf("ERROR. Bad input. For example: 1\n");
        return ERROR;
    }
    ASSERT(0 < primeNumber && primeNumber <= 10000);

    int massOfPrimes[MaxValueOfPrimeNumber];
    memset(massOfPrimes, 0, MaxValueOfPrimeNumber * sizeof(int));

    CreateMassOfPrimes(massOfPrimes);
    ASSERT(0 < massOfPrimes[primeNumber] && massOfPrimes[primeNumber] <= MaxValueOfPrimeNumber);

    OUT printf("%dth prime is:\n", primeNumber);
    printf("%d\n", massOfPrimes[primeNumber]);
    return OK;
}

void CreateMassOfPrimes(int massOfPrimes[])
{
    ASSERT(massOfPrimes != 0);

    int checkPrime[MaxValueOfPrimeNumber];
    memset(checkPrime, 0, MaxValueOfPrimeNumber * sizeof(int));

    CreateMass_checkPrime(checkPrime);

    int counter = 1;
    for (int number = 2; number <= MaxValueOfPrimeNumber; number++)
        {
            if (checkPrime[number] == 0)
                {
                    massOfPrimes[counter++] = number;
                }
        }
}

void CreateMass_checkPrime(int checkPrime[])
{
    ASSERT(checkPrime != 0);

    checkPrime[1] = 1;
    int counter1 = 2;
    while (counter1 <= MaxValueOfPrimeNumber)
    {
        if (checkPrime[counter1] == 0)
        {
            int counter2 = 2 * counter1;
            while (counter2 <= MaxValueOfPrimeNumber)
                {
                    checkPrime[counter2] = 1;
                    counter2 += counter1;
                }
        }
        counter1++;
    }
}

int Task_4C_FlipWord()
{
    char c = ' ';

    int  MaxLength = 1000; //! Maximal length of input string
    char str[MaxLength]; //! input string

    int counter = 0;
    int left = 0, right = 0; //! left and right limits of the word

    OUT printf("Enter your string>\n");

    //! reading character to character and output sought string(answer)
    while(scanf("%c", &c) == 1 && c != '\n')
    {
        if (!isalpha(c))
        {
            for (int i = right - 1; i >= left; i--) //! int i is counter of the cycle
                printf("%c", str[i]);
            left = counter + 1;
            right = left;
            printf("%c", c);
        }

        else    right = counter + 1;
        str[counter++] = c;

    }
    if (isalpha(str[counter - 1])) //!checking if symbol is letter
    {
        for (int i = right - 1; i >= left; i--) //! int i is counter of the cycle
            printf("%c", str[i]);
    }
    printf("\n");
    return OK;
}

int Task_3C_SumOfFourSquares()
{
    int N = 0; //! input number

    int minNumberValue = 0; //! min value of input number
    int maxNumberValue = 2000000; //! max value of input number

    OUT printf("Enter you number:\n");

    if (scanf("%d", &N) != 1)
    {
        OUT printf("ERROR. Bad input. For example: 100\n");
        return ERROR;
    }
    ASSERT(minNumberValue <= N && N <= maxNumberValue);

    int a = 0, b = 0, c = 0, d = 0; //! required number: N = a^2 + b^2 + c^2 + d^2; a <= b <= c <= d
    Brute(N, &a, &b, &c, &d);
    ASSERT(N == a*a + b*b + c*c + d*d);

    OUT printf("%d = ", N);
    printf("%d %d %d %d\n", a*a, b*b, c*c, d*d);
    return OK;
}

int Brute(int N, int* a, int* b, int* c, int* d)
{
    ASSERT(a != 0);
    ASSERT(b != 0);
    ASSERT(c != 0);
    ASSERT(d != 0);

    double sqrtN = sqrt(N);
    for (*d = (int) (sqrtN/2.0); *d <= (int) sqrtN + 1; (*d)++)
    {
        double sqrtNd = sqrt(N - (*d)*(*d));
        for (*c = (int) (sqrtNd/sqrt(3.0)); *c <= (int) sqrtNd + 1; (*c)++)
        {
            double sqrtNdc = sqrt(N - (*d)*(*d) - (*c)*(*c));
            if (*c <= *d)
            {
                for (*b = (int) (sqrtNdc/sqrt(2.0)); *b <= (int) sqrtNdc +1; (*b)++)
                {
                    if (*b <= *c)
                    {
                        int aSquare = N - (*d)*(*d) - (*c)*(*c) - (*b)*(*b);
                        double aDouble = sqrt(aSquare);
                        int aRound = (int) aDouble;
                        if (aSquare == aRound*aRound)
                        {
                            *a = aRound;
                            if (*a <= *b) return OK;
                        }
                    }

                }
            }
        }
    }

    return ERROR;
}

int Task_6C_FreeFromSquares()
{
    int N = 0; //! number of elements

    int minNValue = 0; //! min value of input number of elements
    int maxNValue = 200; //! max value of input number of elements

    int minElementValue = 1; //! min value of element
    int maxElementValue = INT_MAX; //! max value of element

    OUT printf("Enter you number of elements:\n");

    if (scanf("%d", &N) != 1)
    {
        OUT printf("ERROR. Bad input of number of elements. Example: 5\n");
        return ERROR;
    }
    ASSERT(minNValue <= N && N <= maxNValue)

    int arr[N]; //! array of N elements
    memset(arr, 0, N * sizeof(int));

    OUT printf("Enter your input elements:\n");

    for (int i = 0; i < N; i++)
    {
        if (scanf("%d", &arr[i]) != 1)
        {
            OUT printf("ERROR. Bad input of element array. Example: 1\n");
            return ERROR;
        }
        ASSERT(minElementValue <= arr[i] && arr[i] <= maxElementValue);
    }

    int massOfPrimes[MaxValueOfPrimeNumber];
    memset(massOfPrimes, 0, MaxValueOfPrimeNumber * sizeof(int));

    CreateMassOfPrimes(massOfPrimes);
    for (int i = 1; i < NumberOfPrimes; i++)
        ASSERT(0 < massOfPrimes[i] && massOfPrimes[i] <= MaxValueOfPrimeNumber);

    OUT printf("Free from Squares are:\n");
    for (int i = 0; i < N; i++)
    {
        if (ElemHasntSqruares(massOfPrimes, arr[i])) printf("%d ", arr[i]);
    }
    printf("\n");
    return OK;
}

bool ElemHasntSqruares(int massOfPrimes[], int elem)
{
    ASSERT(massOfPrimes != 0);
    for (int i = 1; i < NumberOfPrimes && sqr(massOfPrimes[i]) <= elem; i++)
        if (elem % sqr(massOfPrimes[i]) == 0) return false;
    return true;
}

int Task_9C_SumOfBigBinaryNumbers()
{
    int MaxLength = 1001; //! Max length of binary number
    int numb1[MaxLength], numb2[MaxLength]; //! first and binary number

    memset(numb1, 0, MaxLength * sizeof(int));
    memset(numb1, 0, MaxLength * sizeof(int));

    char input = ' ';

    int length1 = 0, length2 = 0; //! length of first and second number

    OUT printf("Enter first binary number:\n");
    while (scanf("%c", &input) == 1 && input != '\n')
    {
        numb1[length1++] = (int) input - 48;
        ASSERT(0 <= numb1[length1 - 1] && numb1[length1 - 1] <= 1);
    }

    OUT printf("Enter second binary number:\n");
    while (scanf("%c", &input) == 1 && input != '\n')
    {
        numb2[length2++] = (int) input - 48;
        ASSERT(0 <= numb2[length2 - 1] && numb2[length2 - 1] <= 1);
    }

    for (int i = 0; i <= (length1 - 1)/2; i++)
        swap(&numb1[i], &numb1[length1 - 1 - i]);

    for (int i = 0; i <= (length2 - 1)/2; i++)
        swap(&numb2[i], &numb2[length2 - 1 - i]);

    int length = max(length1, length2);

    int result[MaxLength]; //! result of summing
    memset(result, 0, MaxLength * sizeof(int));
    for (int i=0; i < length; i++)
    {
        result[i] += numb1[i] + numb2[i];
        result[i+1] = result[i]/2;
        result[i] %= 2;
        ASSERT(0 <= result[i] && result[i] <= 1);
    }

    while (result[length] == 0)
        length--;

    OUT printf("The result of sum is:\n");
    for (int i = length; i>=0; i--)
        printf("%d", result[i]);
    printf("\n");

    return OK;
}

void swap(int* x, int* y)
{
    ASSERT(x != 0);
    ASSERT(y != 0);
    int z = *x;
    *x = *y;
    *y = z;
}

int Task_5D_NumberOfGoodWords()
{
    int N = 0, K = 0;
    int MinValue = 0, MaxValue = 47;
    OUT printf("Enter length of binary number and and number of ones:\n");

    if (scanf("%d %d", &N, &K) != 2)
    {
        OUT printf("ERROR. Bad input. For example: 4 2\n");
        return ERROR;
    }
    ASSERT(MinValue <= N && N <= MaxValue);
    ASSERT(MinValue <= K && K <= MaxValue);
    ASSERT(N >= K);

    long long result = 0;
    RecursiveBrute(N, K,  0, &result);
    ASSERT(result >= 0);

    OUT printf("Number of Good Words is:\n");
    printf("%I64d\n", result);
    return OK;
}

void RecursiveBrute(int N, int K, int lastByte, long long* result)
{
    ASSERT(result != 0);
    if (N == 0 && K == 0) *result = *result + 1;
    if (N > 0)
    {
        RecursiveBrute(N - 1, K, 0, result);
        if (lastByte == 0 && K > 0) RecursiveBrute(N - 1, K - 1, 1, result);
    }

}

int Task_5C_SortingStudents()
{
    int MaxNameLength = 29; //! max length of student's name
    int MaxNumberOfStudents = 9999; //! max number of students

    int MinRating = 1;
    int MaxRating = 10;

    int numberOfStudents = 0;
    OUT printf("Enter number of students:\n");
    if (scanf("%d", &numberOfStudents) != 1)
    {
        OUT printf("ERROR. Bad number of students input. Example: 3\n");
        return ERROR;
    }
    ASSERT(0 < numberOfStudents && numberOfStudents <= MaxNumberOfStudents);

    char name[numberOfStudents][MaxNameLength];
    memset(name, '\0', numberOfStudents * sizeof(int));

    int rating[numberOfStudents];
    memset(rating, 0, numberOfStudents * sizeof(int));

    char nameAndRating[numberOfStudents][MaxNameLength + 5];
    memset(nameAndRating, '\0', numberOfStudents * sizeof(int));

    for (int i = 0; i < numberOfStudents; i++)
    {
        scanf("%s %d", &name[i], &rating[i]);
        ASSERT(MinRating <= rating[i] && rating[i] <= MaxRating);
        int length = strlen(name[i]);
        ASSERT(0 < length && length <= MaxNameLength);

        nameAndRating[i][0] = ' ';
        for (int j = 0; j < length; j++)
            nameAndRating[i][j+1] = name[i][j];
        if (rating[i] < 10)
        {
            nameAndRating[i][length + 1] = ' ';
            nameAndRating[i][length + 2] = (char) (rating[i] + 48);
            length += 3;
            nameAndRating[i][length] = '\n';
        }
        else
        {
            nameAndRating[i][length + 1] = ' ';
            nameAndRating[i][length + 2] = '1';
            nameAndRating[i][length + 3] = '0';
            length += 4;
            nameAndRating[i][length] = '\n';
        }

    }
    qsort(nameAndRating, numberOfStudents, sizeof(char[MaxNameLength + 5]), (int (*)(const void*,const  void*)) strcmp);

    OUT printf("Result:\n");
    for (int i = 0; i < numberOfStudents; i++)
    {
        int j = 1;
        while (nameAndRating[i][j] != '\n')
            printf("%c", nameAndRating[i][j++]);
        printf("\n");
    }
    printf("\n");
    for (int i = 0; i < numberOfStudents; i++)
    {
        int length = 1;
        while (nameAndRating[i][length] != '\n')
            length++;

        nameAndRating[i][0] = nameAndRating[i][length - 1];
        if (nameAndRating[i][0] == '0') nameAndRating[i][0] = (char) 10;
        nameAndRating[i][0] = (char) (11 - (int) nameAndRating[i][0]);
    }
    qsort(nameAndRating, numberOfStudents, sizeof(char[MaxNameLength + 5]), (int (*)(const void*,const  void*)) strcmp);

    for (int i = 0; i < numberOfStudents; i++)
    {
        int j = 1;
        while (nameAndRating[i][j] != '\n')
            printf("%c", nameAndRating[i][j++]);
        printf("\n");
    }
    return OK;
}

int Task_5B_SumOfDividers()
{
    int MinValueOfN = 1; //! min value of input number
    int MaxValueOfN = (int) pow(2, 28); //! max value of input number
    int N = 0; //! input number
    OUT printf("Enter your input number:\n");
    if (scanf("%d", &N) != 1)
    {
        OUT printf("ERROR. Bad input. Example: 5\n");
        return ERROR;
    }
    ASSERT(MinValueOfN <= N && N <= MaxValueOfN);

    int sumOfDividers = 0;

    for (int i = 1; i <= (int) sqrt(N); i++)
    {
        if (N % i == 0)
        {
            sumOfDividers += i;
            if (i*i != N) sumOfDividers += N/i;
        }
    }
    ASSERT(0 < sumOfDividers);
    OUT printf("Sum of Dividers:\n");
    printf("%d\n", sumOfDividers);
    return OK;
}

int Task_8B_FullSquares()
{
    int N = 0; //! input number of elements
    int MinValueOfN = 1; //! min value of input number of elements
    int MaxValueOfN = 100; //! max value of input number of elements

    OUT printf("Enter your input number of elements:\n");

    if (scanf("%d", &N) != 1)
    {
        OUT printf("ERROR. Bad input. Example: 5\n");
        return ERROR;
    }
    ASSERT(MinValueOfN <= N && N <= MaxValueOfN);

    int arrOfElements[N];
    memset(arrOfElements, 0, N * sizeof(int));

    int MinValueOfElement = 1; //! min value of input number of elements
    int MaxValueOfElement = INT_MAX; //! max value of input number of elements

    OUT printf("Enter your input elements:\n");

    for (int i = 0; i < N; i++)
    {
        if (scanf("%d", &arrOfElements[i]) != 1)
        {
            OUT printf("ERROR. Bad input. Example: 5\n");
            return ERROR;
        }
        ASSERT(MinValueOfElement <= arrOfElements[i] && arrOfElements[i] <= MaxValueOfElement);
        if (IsSquare(arrOfElements[i])) printf("%d ", arrOfElements[i]);
    }
    printf("\n");
    return OK;
}

int IsSquare(int elem)
{
    int ApproximateSqrtElem = (int) sqrt(elem);
    if (sqr(ApproximateSqrtElem) == elem) return TRUE;
    else                                  return FALSE;
}

